package com.softeem.idriveserver.controller;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.softeem.idriveserver.dto.Result;
import com.softeem.idriveserver.entity.Admin;
import com.softeem.idriveserver.service.AdminService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Tag(name = "管理员管理")
@CrossOrigin     //允许来自任意源的访问
@RestController
public class AdminController {

    @Autowired
    private AdminService adminService;

    /**
     * 管理员新增
     * @param username
     * @param password
     * @return
     */
    @Operation(summary = "新增管理员",description = "管理员账号密码，账号不能重复")
    @Parameters({
            @Parameter(name = "username",description = "用户名",required = true),
            @Parameter(name = "password",description = "密码",required = true)
    })
    @PostMapping("/admin")
    public Result add(String username, String password){
        //查询管理员是否重复  select * from admin where username = ?
        Admin admin = adminService.getOne(Wrappers.lambdaQuery(Admin.class).eq(Admin::getUsername, username));
        if (admin != null) {
            return Result.error().setMsg("用户名已存在");
        }
        //生成随机盐
        String token = RandomUtil.randomString(16);
        //将密码和随机盐组合加密
        password = SecureUtil.md5(password + token);
        //根据现有信息构建管理员对象
        admin = new Admin();
        admin.setUsername(username);
        admin.setPassword(password);
        admin.setToken(token);
        return adminService.save(admin) ? Result.ok().setMsg("添加成功").setData(admin) : Result.error().setMsg("添加失败");
    }

    /**
     * 管理员登录
     * @param username
     * @param password
     * @return
     */
    @Operation(summary = "管理员登录",description = "账号密码登录")
    @Parameters({
            @Parameter(name = "username",description = "用户名",required = true),
            @Parameter(name = "password",description = "密码",required = true)
    })
    @GetMapping("/admin/login")
    public Result login(String username,String password){
        Admin admin = adminService.getOne(Wrappers.lambdaQuery(Admin.class).eq(Admin::getUsername, username));
        if(admin == null){
            return Result.error().setMsg("用户不存在");
        }
        if(!SecureUtil.md5(password + admin.getToken()).equals(admin.getPassword())){
            return Result.error().setMsg("密码错误");
        }
        if(admin.getStatus() == 0){
            return Result.error().setMsg("账号被冻结");
        }
        //对密码脱敏
        admin.setPassword("******");
        admin.setToken("******");
        return Result.ok().setMsg("登录成功").setData(admin);
    }

    /**
     * 管理员修改
     * @param admin
     * @return
     */
    @Operation(summary = "管理员修改",description = "根据ID修改管理员信息")
    @PutMapping("/admin")
    public Result modify(@RequestBody Admin admin){
        if(admin.getId() == null){
            return Result.error().setMsg("管理员ID为空");
        }
        //根据ID查询
        Admin a = adminService.getById(admin.getId());
        if(a == null){
            return Result.error().setMsg("管理员不存在");
        }
        if(admin.getPassword() != null && !admin.getPassword().equals(a.getPassword())){
            //生成随机盐
            String token = RandomUtil.randomString(16);
            //将密码和随机盐组合加密
            admin.setPassword(SecureUtil.md5(admin.getPassword() + token));
            admin.setToken(token);
        }
        return adminService.updateById(admin) ? Result.ok().setMsg("修改成功") : Result.error().setMsg("修改失败");
    }

    /**
     * 管理员列表
     * @param page
     * @param limit
     * @return
     */
    @Operation(summary = "管理员列表",description = "分页查询管理员信息")
    @Parameters({
            @Parameter(name = "page",description = "页码",required = true),
            @Parameter(name = "limit",description = "每页记录数",required = true)
    })
    @GetMapping("/admin/list")
    public Result list(@RequestParam(defaultValue = "1") Integer page,@RequestParam(defaultValue = "3")Integer limit){
        //分页查询
        List<Admin> list = adminService.list(new Page<Admin>(page, limit));
        //查询总记录条数
        long total = adminService.count();
        //返回结果
        return Result.ok().setData(list).setCount(total);
    }

    // -DELETE  http://127.0.0.1:8080/admin/10
    /**
     * 管理员删除
     * @param id
     * @return
     */
    @Operation(summary = "管理员删除",description = "根据ID删除管理员信息")
    @Parameters({
            @Parameter(name = "id",description = "管理员ID",required = true)
    })
    @DeleteMapping("/admin/{id}")
    public Result del(@PathVariable Integer id){
        Admin admin = adminService.getById(id);
        if(admin == null){
            return Result.error().setMsg("管理员不存在");
        }
        return adminService.removeById(id) ? Result.ok().setMsg("删除成功") : Result.error().setMsg("删除失败");
    }

    /**
     * 管理员修改密码
     * @param id
     * @param oldPwd
     * @param newPwd
     * @return
     */
    @Operation(summary = "管理员修改密码",description = "根据ID修改管理员密码")
    @Parameters({
            @Parameter(name = "id",description = "管理员ID",required = true),
            @Parameter(name = "oldPwd",description = "旧密码",required = true),
            @Parameter(name = "newPwd",description = "新密码",required = true)
    })
    @PutMapping("/admin/pwd")
    public Result modifyPwd(Integer id,String oldPwd,String newPwd){
        //根据id查询管理员
        Admin admin = adminService.getById(id);
        //判断管理员是否存在
        if(admin == null){
            return Result.error().setMsg("管理员不存在");
        }
        //将输入的旧密码和盐组合加密后与数据库查询到的密码对比
        if(!SecureUtil.md5(oldPwd + admin.getToken()).equals(admin.getPassword())){
            return Result.error().setMsg("旧密码错误");
        }
        //重新生成盐（token）
        String token = RandomUtil.randomString(16);
        //将生成的盐和新密码组合加密
        newPwd = SecureUtil.md5(newPwd + token);

        admin.setPassword(newPwd);
        admin.setToken(token);
        //执行密码修改操作并返回结果
        return adminService.updateById(admin) ? Result.ok().setMsg("修改成功") : Result.error().setMsg("修改失败");
    }
}
